import { Component, Vue, Prop, PropSync, Watch, Emit } from 'vue-property-decorator';

/** 匹配括号和其中数字 */
var reg = /\(.*?\)/g;
@Component({})
export default class AppTree extends Vue {
  @Prop({
    required: true,
    default: () => { },
  }) treeConfig!: any

  @Prop({
    required: false,
    default: () => () => {
      return new Promise<void>(resolve => {
        resolve();
      });
    },
  }) onLoadData!: Function

  @Prop({
    required: false,
    default: () => () => { },
  }) handle!: Function

  @Prop({
    required: false,
    default: () => () => { },
  }) onSearch!: Function

  @Prop({
    required: false,
    default: () => () => { },
  }) onSelect!: Function

  @PropSync('treeData', {
    required: false,
    default: () => [],
  }) _treeData!: any[]

  @Prop({
    required: false,
    default: () => [],
  }) selectedKeys?: Array<Number | string>;

  Keys: any[] = [];
  searchValue: string = '';
  /** 保存的数信息用于修改 */
  selfTree = this._treeData || [];

  @PropSync("checkedKeys", {
    required: false,
    default: () => [],
  })checkeds!: any[];

  @PropSync("expandedKeys", {
    required: false,
    default: () => [],
  })expandeds!: any[];

  @Emit("selectNode")
  selectNode(node: any) {
    return node;
  }

  @Watch('selectedKeys')
  onKeysChange(val: any[]) {
    this.Keys = val;
  }

  @Watch("_treeData")
  onTreeDataChange() {
    this.selfTree = this._treeData || [];
  }

  nodeClick(selectedKeys: any[], data?: any) {
    if (this.treeConfig?.onlySelect && !data.selected) {
      this.Keys = [data.node.dataRef.id];
    }
    data.node.dataRef.parent = data.node.$parent.dataRef;
    this.selectNode(data.node.dataRef);
  }

  private findSelfNode(nodeList: any, id: string | number, findParent: boolean = false): any {
    let children;
    if (Array.isArray(nodeList)) {
      children = nodeList;
    } else if (typeof nodeList === "object" && nodeList.children) {
      children = nodeList.children;
    }
    const result = children?.find((item: any) => String(item.id) === String(id));
    if (result) {
      return findParent ? nodeList : result;
    } else {
      for (let i = 0; i < children.length; i++) {
        const childResult = this.findSelfNode(children[i], id, findParent);
        if (childResult) {
          return childResult;
        }
      }
    }
  }

  findAllCheckedNode() {
    let result: any[] = [];
    /**
     * 添加所有选中节点
     * @param nodeList 节点列表
     * @param parentChecked 父节点是否被选中
     */
    const findCheckedNode = (nodeList: any[], parentChecked: boolean = false) => {
      nodeList.forEach(node => {
        const checked = this.checkeds.indexOf(node.id) > -1 || parentChecked;
        if (checked) {
          result.push(node);
          if (this.checkeds.indexOf(node.id) === -1) {
            this.checkeds.push(node.id);
          }
        }
        if (node.children && node.children.length > 0) {
          findCheckedNode(node.children, checked);
        }
      });
    }
    findCheckedNode(this.selfTree);
    return result;
  }

  findNode(id: string | number, findParent: boolean = false) {
    return this.findSelfNode(this.selfTree, id, findParent);
  }

  /**
   * @param id 需要删除当前节点id
   */
  deleteNode(id: string | number) {
    const parentNode = this.findNode(id, true);
    parentNode.children = parentNode.children.filter((item: any) => String(item.id) !== String(id));
    const length = parentNode.children.length;
    if (length > 0) {
      parentNode.label = parentNode.label.replace(reg, "") + `(${length})`;
      this.Keys = [parentNode.children[0].id];
      return parentNode.children[0].id;
    } else {
      parentNode.label = parentNode.label.replace(reg, "");
      parentNode.isLeaf = true;
      this.Keys = [parentNode.id];
      return parentNode.id;
    }
  }

  /**
   *
   * @param id 父级节点id
   * @param data 添加子项数据： Object
   */
  addChildNode(id: string | number, data: any) {
    const node = this.findNode(id);
    node.isLeaf = false;
    node.children = [
      ...(node.children || []),
      data
    ];
    node.label = node.label.replace(reg, "") + `(${node.children.length})`;
    this.treeConfig.defaultExpandedKeys.push(id);
  }

  /**
   *
   * @param id: 当前节点id
   * @param label 更改后label
   */
  changeNodeLabel(id: string | number, label: string) {
    const node = this.findNode(id);
    const numberString = node.label.match(reg);
    node.label = label + (numberString ? numberString[0] : '');
  }

  handleChange(val: any) {
    this.handle(val);
  }

  check(checkedKeys: any[], evt: any) {
    if (this.treeConfig.check) {
      this.treeConfig.check(checkedKeys, evt)
    } else {
      this.checkeds = checkedKeys;
    }
  }
}
